package com.shuyun.ccms.encrypt.common;

import java.io.*;
import java.sql.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Sets;
import com.shuyun.ccms.encrypt.util.PropertyUtil;
import com.shuyun.crypt.CryptTools;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;




import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.shuyun.ccms.encrypt.util.ConnectionUtil;
import org.springframework.util.CollectionUtils;

public class DataValid {
	private static Logger logger = LoggerFactory.getLogger(DataValid.class);

	public static boolean checkInfo(Connection conn,
									String targetTable,List<String> targetSelectFiled,
									String orignTable,List<String> orignSelectFiled) throws Exception{
									//targetSelectFiled第一位为主键，用于新旧map对比的key,orignSelectFiled的顺序必须与orignSelectFiledEncryptType的顺序一致，不然解密出来的东西不一样

		boolean result = false;
		PreparedStatement ps = null;
		Statement insertSt = null;
		ResultSet rs = null;
		StringBuffer orignSql ;
		StringBuffer targetSql ;
		Map<String,Map<String,String>> custMap = Maps.newConcurrentMap();

		/**
		 * 原始数据栏位:             customerno, full_name , mobile , fullname_modified , mobile_modified , fullname_most , mobile_most
		 * 加密后数据栏位:customerno,customerno_encrypt,full_name_encrypt, mobile_encrypt, fullname_modified_encrypt,mobile_modified_encrypt,fullname_most_encrypt,mobile_most_encrypt,phone_most_encrypt
		 */
		try{
			//先随机抽取部分数据
			for(DataLimit dataLimit : DataLimit.values()){
				targetSql = new  StringBuffer();

				targetSql.append(" select ").append(StringUtils.join(targetSelectFiled, ","));
				targetSql.append(" from ").append(targetTable);
				targetSql.append(" limit ").append(dataLimit.getValue()).append(", 3");

				ps = conn.prepareStatement(targetSql.toString());
				rs = ps.executeQuery();
				while(rs.next()){
					Map<String,String> encryptMap = Maps.newHashMap();
					String mapKey = rs.getString(targetSelectFiled.get(0));
					for (int i = 1; i < targetSelectFiled.size(); i++){//这里不去第一个，运维第一个是主键
						encryptMap.put(targetSelectFiled.get(i),rs.getString(targetSelectFiled.get(i)));
					}
					custMap.put(mapKey, encryptMap);
				}
			}
			//再去取原始数据
			orignSql = new  StringBuffer();
			orignSql.append(" select ").append(StringUtils.join(orignSelectFiled, ","));
			orignSql.append(" from ").append(orignTable);
			orignSql.append(" where ").append( orignSelectFiled.get (0)).append(" in (").append(setToString(custMap.keySet())).append(")");
			ps = conn.prepareStatement(orignSql.toString());
			rs = ps.executeQuery();
			int allCount = 0;
			while(rs.next()){
				String orign_key = rs.getString(orignSelectFiled.get(0));
				Map<String,String> encryptMap = custMap.get(orign_key);
				for (int i = 0; i< orignSelectFiled.size(); i++){
					String targetString = encryptMap.get(targetSelectFiled.get(i+1));//targetSelectFiled的第一个是主键，要+1
					String orignString = rs.getString(orignSelectFiled.get(i));
					if (targetString == null && orignString == null){
						continue;
					}
					if ((targetString == null && orignString != null)||(targetString != null && orignString == null)){
						return result;
					}
					String dataType = getDataTypeByFiled(orignSelectFiled.get(i));
					logger.info("校验表:{},orign:{},target:{},dataType:{}",targetTable,orignString,targetString,dataType);
					if (!CryptTools.decrypt(targetString,dataType).equals(orignString)){
						return result;//如果不相等，直接返回false
					}
					allCount++;
				}

			}
			if (allCount>0) {//如果没数据也返回false
				return true;
			}
		} catch (Exception e) {
			//conn.rollback();
			e.printStackTrace();
			logger.error("校验加密数据失败. " + e.getMessage());
			return false;
//				throw e;
		}finally{
			ConnectionUtil.newInstance().close(ps, rs);
			ConnectionUtil.newInstance().closeStatement(insertSt);
		}
		return result;
	}

	private static String getDataTypeByFiled(String filedString) {
//		if (nickType.contains(filedString)){
		if (filedString.contains("custom")
				||filedString.contains("pin")
				||filedString.contains("full_name")
				||filedString.contains("fullname")){
			return CryptTools.TYPE_NICK;
		}else if (filedString.contains("phone")||filedString.contains("mobile")){
//		}else if (phoneType.contains(filedString)){
			return CryptTools.TYPE_PHONE;
		}else if (filedString.contains("receiver_name")||filedString.contains("consignee_name")||filedString.contains("recipient_name")){
//		}else if (reciveNameType.contains(filedString)){
			return CryptTools.TYPE_RECEIVER_NAME;
		}
		return CryptTools.TYPE_NICK;
	}


	public static boolean checkTaobaoCustomerInfo(Connection conn) throws Exception{
			PreparedStatement ps = null;
			Statement insertSt = null;
			ResultSet rs = null;
			StringBuffer orignSql ;
			StringBuffer targetSql ;
			List<String> custList = Lists.newArrayList();
			Map<String,Map<String,String>> custMap = Maps.newConcurrentMap();

			/**
			 * 原始数据栏位:             customerno, full_name , mobile , fullname_modified , mobile_modified , fullname_most , mobile_most
			 * 加密后数据栏位:customerno,customerno_encrypt,full_name_encrypt, mobile_encrypt, fullname_modified_encrypt,mobile_modified_encrypt,fullname_most_encrypt,mobile_most_encrypt,phone_most_encrypt
			 */
			try{
				//先随机抽取部分数据
				for(DataLimit dataLimit : DataLimit.values()){
					targetSql = new  StringBuffer();
					Map<String,String> encryptMap = Maps.newConcurrentMap();

					targetSql.append(" select customerno, customerno_encrypt , full_name_encrypt, mobile_encrypt,fullname_modified_encrypt,mobile_modified_encrypt,fullname_most_encrypt,mobile_most_encrypt ");
					targetSql.append(" from tb_taobao_customer_info ");
					targetSql.append(" limit ").append(dataLimit.getValue()).append(", 3");

					ps = conn.prepareStatement(targetSql.toString());
					rs = ps.executeQuery();
					while(rs.next()){
						String customerno = rs.getString("customerno");
						custList.add(customerno);
						encryptMap.put("customerno_encrypt", rs.getString("customerno_encrypt"));
						encryptMap.put("full_name_encrypt", rs.getString("full_name_encrypt"));
						encryptMap.put("mobile_encrypt", rs.getString("mobile_encrypt"));
						encryptMap.put("fullname_modified_encrypt", rs.getString("fullname_modified_encrypt"));
						encryptMap.put("mobile_modified_encrypt", rs.getString("mobile_modified_encrypt"));
						encryptMap.put("fullname_most_encrypt", rs.getString("fullname_most_encrypt"));
						encryptMap.put("mobile_most_encrypt", rs.getString("mobile_most_encrypt"));
						custMap.put(customerno, encryptMap);
					}


				}
				orignSql = new  StringBuffer();
				orignSql.append(" select customerno, full_name , mobile ,fullname_modified , mobile_modified , fullname_most , mobile_most ");
				orignSql.append(" from plt_taobao_customer ");
				orignSql.append(" where customerno in (").append(setToString(custMap.keySet())).append(")");
				ps = conn.prepareStatement(orignSql.toString());
				rs = ps.executeQuery();
				while(rs.next()){
					String orign_customerno = CryptTools.encrypt(rs.getString("customerno"), CryptTools.TYPE_NICK);
					String orign_full_name = CryptTools.encrypt(rs.getString("full_name"), CryptTools.TYPE_NICK);
					String orign_mobile = CryptTools.encrypt(rs.getString("mobile"), CryptTools.TYPE_PHONE);
					String orign_fullname_modified = CryptTools.encrypt(rs.getString("fullname_modified"),CryptTools.TYPE_NICK);
					String orign_mobile_modified = CryptTools.encrypt(rs.getString("mobile_modified"),CryptTools.TYPE_PHONE);
					String orign_fullname_most = CryptTools.encrypt(rs.getString("fullname_most"),CryptTools.TYPE_NICK);
					String orign_mobile_most = CryptTools.encrypt(rs.getString("mobile_most"), CryptTools.TYPE_PHONE);
					Map<String,String> encryptMap = custMap.get(orign_customerno);

					if (orign_customerno.equals(encryptMap.get("customerno_encrypt"))
							&&orign_full_name.equals(encryptMap.get("full_name_encrypt"))
							&&orign_mobile.equals(encryptMap.get("full_name_encrypt"))
							&&orign_full_name.equals(encryptMap.get("full_name_encrypt"))
							&&orign_fullname_modified.equals(encryptMap.get("full_name_encrypt"))
							&&orign_mobile_modified.equals(encryptMap.get("full_name_encrypt"))
							&&orign_fullname_most.equals(encryptMap.get("full_name_encrypt"))
							&&orign_mobile_most.equals(encryptMap.get("full_name_encrypt"))
							){
						return true;
					}
				}

			} catch (Exception e) {
				//conn.rollback();
				e.printStackTrace();
				logger.error("校验淘宝custom数据失败. " + e.getMessage());
				return false;
//				throw e;
			}finally{
				ConnectionUtil.newInstance().close(ps, rs);
				ConnectionUtil.newInstance().closeStatement(insertSt);
			}
		 return false;
	 }


	 public static boolean checkCount(Connection conn,String orginTable, String targetTable) throws Exception{
		PreparedStatement ps = null;
		Statement insertSt = null;
		ResultSet rs = null;
		StringBuffer orignSql = new StringBuffer();
		StringBuffer targetSql = new  StringBuffer();
		Map<String,Integer> result = Maps.newConcurrentMap();
		Integer targetCount = 0;
		Integer orignCount = 0;
		try{
			orignSql.append(" select count(1) as cnt from ").append(orginTable);
			targetSql.append(" select count(1) as cnt from ").append(targetTable);
			ps = conn.prepareStatement(targetSql.toString());
			rs = ps.executeQuery();
			while(rs.next()){
				targetCount = rs.getInt(1);
			}
			ps = conn.prepareStatement(orignSql.toString());
			rs = ps.executeQuery();
			while(rs.next()){
				orignCount = rs.getInt(1);
			}
			if (orignCount > targetCount){
				return false;
			}else {
				return true;
			}

		}catch(Exception e){
			logger.info("数据校验出错-检查count",e);
			return false;
		}finally{
			ConnectionUtil.newInstance().close(ps, rs);
			ConnectionUtil.newInstance().closeStatement(insertSt);
		}
	 }

	public static void main(String[] args) throws IOException {
		test();
//		String tenantFile = PropertyUtil.getValue("tenantId.path");
//		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(tenantFile)));
//		String tenantId;
//		while(StringUtils.isNotBlank(tenantId = br.readLine())){
//			for(DataLimit dataLimit : DataLimit.values()){
//				System.out.println(dataLimit.getValue()+tenantId);
//			}
//		}
	}

	private static void test(){
		String [] arr = "customerno,customerno_encrypt,full_name_encrypt, mobile_encrypt,phone_encrypt,fullname_modified_encrypt,mobile_modified_encrypt,fullname_most_encrypt,mobile_most_encrypt,phone_most_encrypt".split(",");
		List<String> aa = Arrays.asList(arr);
		System.out.println(aa);
	}

	private static String setToString(Set<String> set){
		StringBuffer sb = new StringBuffer();
		String result = null;
		for (String string:set){
			sb.append("\"").append(string).append("\",");
		}
		if (sb.length()!=0){
			result = sb.substring(0,sb.length()-1);
		}
		return result;
	}
}
